package com.chhuang.ewcrm.thread;

import com.chhuang.ewcrm.App;
import com.chhuang.ewcrm.bean.CameraBean;
import com.chhuang.ewcrm.config.PropertiesUtil;
import com.chhuang.ewcrm.cons.Constants;
import com.chhuang.ewcrm.dao.WCameraDao;
import com.chhuang.ewcrm.date.DateUtil;
import com.chhuang.ewcrm.entity.WCamera;
import com.chhuang.ewcrm.frame.CameraFrame;
import com.chhuang.ewcrm.hc.HCNetSDK;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.ptr.IntByReference;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.io.File;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

/**
 * 打开监控摄像头工作线程
 * @author chhuang
 * @create 2020-10-12-14:45
 */
public class InitCameraThread implements Runnable{
    private final Logger logger = LoggerFactory.getLogger(InitCameraThread.class);

    //海康威视SDK
    private static HCNetSDK hcNetSDK;
    private HCNetSDK.NET_DVR_PICCFG_V30 m_struPicCfg;//图像参数,初始化后直接指向通道配置里的图像参数结构体
//    private static PlayCtrl playControl;

    //回调预览时播放库端口指针
//    private NativeLongByReference m_lPort;

    //摄像头对像
    private final List<CameraBean> cameraBeans = new LinkedList<CameraBean>();

    //频道为1
    private static final NativeLong DEF_CHANNEL = new NativeLong(1);

    private WCameraDao wCameraDao = App.getSession().getMapper(WCameraDao.class);

    public InitCameraThread(){
//        m_lPort = new NativeLongByReference(new NativeLong(-1));
    }

    @Override
    public void run() {
        // 显示应用 GU
        initHC();
    }

    /**
     * 初始化海康威视监控
     */
    private void initHC() {
        //获取摄像头配置信息
        WCamera wca = new WCamera();
        wca.setCameraEnable(true);
        List<WCamera> wCameras = wCameraDao.query(wca);
        if(wCameras!=null && !wCameras.isEmpty()){
            javax.swing.SwingUtilities.invokeLater(()-> {
                int cameraNum = wCameras.size();

                CameraFrame cameraFrame = CameraFrame.getCameraFrame(cameraNum);

                hcNetSDK = HCNetSDK.INSTANCE;
//              playControl = PlayCtrl.INSTANCE;

                //初始化
                if(!hcNetSDK.NET_DVR_Init()){
                    logger.error("初始化失败");
                    return ;
                }

                //创建设备
                HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
//              logger.debug("设备信息:" +deInfo.toString());

                for (WCamera wCamera: wCameras){
                    Panel panelRealplay = new Panel();
                    panelRealplay.setBackground(new Color(147,112,219));
                    cameraFrame.addCamerasPanel(panelRealplay);

                    CameraBean cameraBean = new CameraBean(wCamera);
//
                    cameraBean = viewCamera(cameraBean, deInfo, panelRealplay);
                    if(cameraBean!=null){
                        logger.debug(cameraBean.toString());
                        cameraBeans.add(cameraBean);
                    }
                }

            });
        }
    }

    /**
     * 打开预览
     * @param cameraBean
     * @param deInfo
     * @param panelRealplay
     * @return
     */
    private CameraBean viewCamera(CameraBean cameraBean, HCNetSDK.NET_DVR_DEVICEINFO_V30 deInfo, Panel panelRealplay){
        //注册用户设备
        NativeLong userId = hcNetSDK.NET_DVR_Login_V30(cameraBean.getIp(), cameraBean.getPort(),
                cameraBean.getUsername(), cameraBean.getPassword(), deInfo);
        cameraBean.setUserId(userId);
        if(userId.longValue()==-1){
            logger.error("注册失败，错误码为：" + hcNetSDK.NET_DVR_GetLastError());
            return cameraBean;
        }

        m_struPicCfg = new HCNetSDK.NET_DVR_PICCFG_V30();
        m_struPicCfg.write();
        boolean getDVRConfigSuc = hcNetSDK.NET_DVR_GetDVRConfig(userId, HCNetSDK.NET_DVR_GET_PICCFG_V30,
                DEF_CHANNEL, m_struPicCfg.getPointer(), m_struPicCfg.size(), new IntByReference(0));
        m_struPicCfg.read();
        if(!getDVRConfigSuc)logger.error("获取图片参数失败");

//        m_struPicCfg.struMotion.byMotionSensitive = 2;/*移动侦测灵敏度, 0 - 5,越高越灵敏,oxff关闭*/
        m_struPicCfg.struMotion.byPrecision = 1; /* 移动侦测算法的精度: 0--16*16, 1--32*32, 2--64*64 ... */

        m_struPicCfg.write();
        boolean setDVRConfigSuc = hcNetSDK.NET_DVR_SetDVRConfig(userId, HCNetSDK.NET_DVR_SET_PICCFG_V30,
                DEF_CHANNEL, m_struPicCfg.getPointer(), m_struPicCfg.size());
        m_struPicCfg.read();
        if(!setDVRConfigSuc)logger.error("设置图片参数失败");

        //启动实时预览功能  创建clientInfo对象赋值预览参数
        HCNetSDK.NET_DVR_CLIENTINFO clientInfo = new HCNetSDK.NET_DVR_CLIENTINFO();

        //设置设备通道号
        clientInfo.lChannel = DEF_CHANNEL;//预览通道号

        logger.debug("视频区域是否显示："+panelRealplay.isDisplayable());
        //开启实时预览
        clientInfo.hPlayWnd = new W32API.HWND(Native.getComponentPointer(panelRealplay)); //播放窗口的句柄，为NULL表示不显示图像
        NativeLong lRealPlayHandle = hcNetSDK.NET_DVR_RealPlay_V30(userId, clientInfo, null, null, true);
        //开启回调预览
//        clientInfo.hPlayWnd = null; //播放窗口的句柄，为NULL表示不显示图像
//       NativeLong lRealPlayHandle = hcNetSDK.NET_DVR_RealPlay_V30(cameraBean.getUserId(), clientInfo, new FRealDataCallBack(panelRealplay), null, true);

        //判断是否预览成功
        if(lRealPlayHandle.longValue()==-1){
            logger.error("预览失败   错误代码为："+hcNetSDK.NET_DVR_GetLastError());
            close();
        }
//        panelRealplay.repaint();

        cameraBean.setLRealPlayHandle(lRealPlayHandle);
        return cameraBean;
    }

    /**
     * 抓拍图片
     * @return
     */
    private static final String JPG = ".jpg";
    public boolean capturePic(String dir){
        boolean success = false;
        if(!cameraBeans.isEmpty()) {
            for (CameraBean cameraBean: cameraBeans) {
                if(cameraBean.isEnableCapture()){
                    HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
                    jpegpara.wPicSize=2;
                    jpegpara.wPicQuality=1;
                    String picPath = dir + cameraBean.getIp().replaceAll("\\.","_") + JPG;
                    success = hcNetSDK.NET_DVR_CaptureJPEGPicture(cameraBean.getUserId(), DEF_CHANNEL, jpegpara, picPath);
                    if(!success)
                        logger.error(cameraBean.getIp()+ "图片抓拍失败：" + hcNetSDK.NET_DVR_GetLastError());
                }
            }
        }
        return success;
    }

    /**
     *
     * @param millis
     */
    private void sleep(long millis){
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭
     */
    public void close(){
        CameraFrame.exit();
        if(!cameraBeans.isEmpty()){
            for(CameraBean cameraBean : cameraBeans){
                if(cameraBean!=null){
                    if(cameraBean.getLRealPlayHandle()!=null && cameraBean.getLRealPlayHandle().longValue()!=-1){
                        //停止预览
                        hcNetSDK.NET_DVR_StopRealPlay(cameraBean.getLRealPlayHandle());
                    }
                    if(cameraBean.getUserId()!=null && cameraBean.getUserId().longValue()!=-1){
                        //注销用户
                        hcNetSDK.NET_DVR_Logout(cameraBean.getUserId());
                    }
                }
            }
            //释放SDK资源
            hcNetSDK.NET_DVR_Cleanup();
        }
    }


//    class FRealDataCallBack implements HCNetSDK.FRealDataCallBack_V30{
//        private Panel panelRealplay;
//        public FRealDataCallBack(Panel panelRealplay){
//            this.panelRealplay = panelRealplay;
//        }
//        //预览回调
//        public void invoke(NativeLong lRealHandle, int dwDataType, ByteByReference pBuffer, int dwBufSize, Pointer pUser) {
//            W32API.HWND hwnd = new W32API.HWND(Native.getComponentPointer(panelRealplay));
//            switch (dwDataType){
//                case HCNetSDK.NET_DVR_SYSHEAD: //系统头
//                    if (!playControl.PlayM4_GetPort(m_lPort)) {//获取播放库未使用的通道号
//                        break;
//                    }
//
//                    if (dwBufSize > 0){
//                        if (!playControl.PlayM4_SetStreamOpenMode(m_lPort.getValue(), PlayCtrl.STREAME_REALTIME)) {//设置实时流播放模式
//                            break;
//                        }
//
//                        if (!playControl.PlayM4_OpenStream(m_lPort.getValue(), pBuffer, dwBufSize, 1024 * 1024)) {//打开流接口
//                            break;
//                        }
//
//                        if (!playControl.PlayM4_Play(m_lPort.getValue(), hwnd)) {//播放开始
//                            break;
//                        }
//                    }
//                case HCNetSDK.NET_DVR_STREAMDATA:   //码流数据
//                    if ((dwBufSize > 0) && (m_lPort.getValue().intValue() != -1)){
//                        if (!playControl.PlayM4_InputData(m_lPort.getValue(), pBuffer, dwBufSize)){//输入流数据
//                            break;
//                        }
//                    }
//            }
//        }
//    }
}
